home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dbg / sun4.md / dbgIP.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  10KB  |  344 lines

  1. /* 
  2.  * dbgIP.c --
  3.  *
  4.  *    Routines to handle the IP/UDP protocol for the debugger. Validates
  5.  *    input packets and formats pacjkets for output.
  6.  *
  7.  * Copyright 1987 Regents of the University of California
  8.  * All rights reserved.
  9.  */
  10.  
  11. #ifndef lint
  12. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dbg/sun4.md/dbgIP.c,v 9.2 90/09/24 16:58:50 kupfer Exp $ SPRITE (Berkeley)";
  13. #endif not lint
  14.  
  15. #include <sprite.h>
  16. #include <dbg.h>
  17. #include <sys.h>
  18. #include <user/net.h>
  19. #include <stdio.h>
  20.  
  21. extern    int    dbgTraceLevel;
  22.  
  23. /*
  24.  * Forward declarations.
  25.  */
  26.  
  27. #ifdef DEBUG
  28. static void     TestInputProc _ARGS_((int size, Net_IPHeader *headerPtr));
  29. static char *    ProtNumToName _ARGS_((int num));
  30. #endif
  31.  
  32.  
  33. /*
  34.  *----------------------------------------------------------------------
  35.  *
  36.  * Dbg_ValidatePacket --
  37.  *
  38.  *    This routine checks to see if an IP/UDP packet is proper. This
  39.  *    involves checking for the the proper sizes and that the packet 
  40.  *    has not been corrupted. The packet is checked to see if has the 
  41.  *    right UDP port. If the port matches then it is assumed that the 
  42.  *    packet is addressed to us.
  43.  *
  44.  *    Note: IP options processing and fragment reasssembly are not done.
  45.  *
  46.  * Results:
  47.  *    TRUE if packet processed successfully.
  48.  *
  49.  * Side effects:
  50.  *    None.
  51.  *
  52.  *----------------------------------------------------------------------
  53.  */
  54.  
  55. Boolean
  56. Dbg_ValidatePacket(size, ipPtr, lenPtr, dataPtrPtr, 
  57.         destIPAddrPtr, srcIPAddrPtr, srcPortPtr)
  58.  
  59.     int                size;        /* IP packet size in bytes. */
  60.     register Net_IPHeader    *ipPtr;        /* Ptr to IP packet buffer. */
  61.     int                *lenPtr;    /* Size of data in bytes.(out)*/
  62.     Address            *dataPtrPtr;    /* Address of data in the
  63.                          * in the packet. (out) */
  64.     Net_InetAddress        *destIPAddrPtr;    /* IP addr of this machine. 
  65.                          * (out) */
  66.     Net_InetAddress        *srcIPAddrPtr;    /* IP addr of sender. (out) */
  67.     unsigned int        *srcPortPtr;    /* UDP port from the sender
  68.                          * (needed to reply to the 
  69.                          * sender). */
  70. {
  71.     register Net_UDPHeader    *udpPtr;
  72.     register int        headerLenInBytes;
  73.  
  74.     if (size < sizeof(Net_IPHeader)) {
  75.     if (dbgTraceLevel >= 4) {
  76.         printf("Dbg_ValidatePacket: Bad size %d\n", size);
  77.     }
  78.     return(FALSE);
  79.     }
  80.  
  81.     headerLenInBytes = ipPtr->headerLen * 4;
  82.     udpPtr = (Net_UDPHeader *) ((Address) ipPtr + headerLenInBytes);
  83.  
  84.     /*
  85.      * Validate the IP/UDP packet. The packet is checked for the following:
  86.      *  1) have a proper IP header length,
  87.      *  2) the total length of the packet must be larger than the IP header,
  88.      *  3) the IP checksum is ok,
  89.      *  4) the protocol is UDP,
  90.      *  5) the UDP packet length is proper,
  91.      *  6) the UDP dest. port matches the given port #,
  92.      *  7) the IP packet is not a fragment.
  93.      *
  94.      * The checks are done in order of importance and likelihood of being false.
  95.      * For instance, the header length should be validated before accessing
  96.      * fields in the header and it is more likely that the UDP port won't match
  97.      * than the packet is a fragment.
  98.      */
  99.     if (headerLenInBytes < sizeof(Net_IPHeader)) {
  100.     if (dbgTraceLevel >= 5) {
  101.         printf("Failed case 1: %d\n", headerLenInBytes);
  102.     }
  103.     return(FALSE);
  104.     } else if (Net_NetToHostShort(ipPtr->totalLen) < ipPtr->headerLen) {
  105.     if (dbgTraceLevel >= 5) {
  106.         printf("Failed case 2: %d, %d\n", 
  107.             Net_NetToHostShort(ipPtr->totalLen), ipPtr->headerLen);
  108.     }
  109.     return(FALSE);
  110.     } else if (Net_InetChecksum(headerLenInBytes, (Address) ipPtr) != 0) {
  111.     if (dbgTraceLevel >= 5) {
  112.         printf("Failed case 3 (IP checksum: %x)\n", ipPtr->checksum);
  113.     }
  114.     return(FALSE);
  115.     } else if (ipPtr->protocol != NET_IP_PROTOCOL_UDP) {
  116.     if (dbgTraceLevel >= 5) {
  117.         printf("Failed case 4: %d\n", ipPtr->protocol);
  118.     }
  119.     return(FALSE);
  120.     } else if (Net_NetToHostShort(udpPtr->len) < sizeof(Net_UDPHeader)) {
  121.     if (dbgTraceLevel >= 5) {
  122.         printf("Failed case 5: %d, %d\n",
  123.             Net_NetToHostShort(udpPtr->len), sizeof(Net_UDPHeader));
  124.     }
  125.     return(FALSE);
  126.     } else if (Net_NetToHostShort(udpPtr->destPort) < DBG_UDP_PORT) {
  127.     if (dbgTraceLevel >= 5) {
  128.         printf("Failed case 6: %d, %d\n", 
  129.             Net_NetToHostShort(udpPtr->destPort), DBG_UDP_PORT);
  130.     }
  131.     return(FALSE);
  132.     } else if ((ipPtr->flags & NET_IP_MORE_FRAGS) || (ipPtr->fragOffset != 0)) {
  133.     if (dbgTraceLevel >= 5) {
  134.         printf("Failed case 7: %d, %d\n",
  135.         (ipPtr->flags & NET_IP_MORE_FRAGS), (ipPtr->fragOffset != 0));
  136.     }
  137.     return(FALSE);
  138.     } 
  139.  
  140.     /*
  141.      * If the UDP packet was sent with a checksum, the checksum will be
  142.      * non-zero.
  143.      */
  144.     if (udpPtr->checksum != 0) {
  145.     Net_IPPseudoHdr        pseudoHdr;
  146.  
  147.     /*
  148.      * The checksum is computed for the IP "pseudo-header" and
  149.      * the UDP header and data. When the UDP checksum was calculated,
  150.      * the checksum field in the header was set to zero. When we 
  151.      * recalculate the value, we don't zero the field so the computed 
  152.      * value should be zero if the packet didn't get garbled.
  153.      */
  154.     pseudoHdr.source    = ipPtr->source;
  155.     pseudoHdr.dest        = ipPtr->dest;
  156.     pseudoHdr.zero        = 0;
  157.     pseudoHdr.protocol    = ipPtr->protocol;
  158.     pseudoHdr.len        = udpPtr->len;
  159.     if (Net_InetChecksum2((int) udpPtr->len, (Address) udpPtr, 
  160.         &pseudoHdr) != 0) {
  161.  
  162.         if (dbgTraceLevel >= 4) {
  163.         printf("Dbg_ValidatePacket: Bad UDP checksum: %x\n", 
  164.                 udpPtr->checksum);
  165.         }
  166.         return(FALSE);
  167.     }
  168.     }
  169.  
  170.     *lenPtr       = Net_NetToHostShort(udpPtr->len) - sizeof(Net_UDPHeader);
  171.     *dataPtrPtr       = ((Address) udpPtr) + sizeof(Net_UDPHeader);
  172.     *destIPAddrPtr = Net_NetToHostInt(ipPtr->dest);
  173.     *srcIPAddrPtr  = Net_NetToHostInt(ipPtr->source);
  174.     *srcPortPtr       = Net_NetToHostShort(udpPtr->srcPort);
  175.  
  176.     if (dbgTraceLevel >= 4) {
  177.     printf("Dbg_ValidatePacket: Good packet\n");
  178.     }
  179.     return(TRUE);
  180. }
  181.  
  182.  
  183. /*
  184.  *----------------------------------------------------------------------
  185.  *
  186.  * Dbg_FormatPacket --
  187.  *
  188.  *    Formats an IP/UDP packet for sending on the network.
  189.  *    The first Dbg_PacketHdrSize() bytes of *dataPtr must not be used -- 
  190.  *    this area is filled in with the IP and UDP headers.
  191.  *    The IP addresses and UDP port arguments are assumed to be in the
  192.  *    machine's native byte order. They are converted to network
  193.  *    byte order when the header is formatted.
  194.  *
  195.  *    Note: The IP header checksum is computed but the UDP checksum is not. 
  196.  *
  197.  * Results:
  198.  *    None.
  199.  *
  200.  * Side effects:
  201.  *    None.
  202.  *
  203.  *----------------------------------------------------------------------
  204.  */
  205.  
  206. void
  207. Dbg_FormatPacket(srcIPAddress, destIPAddress, destPort, dataSize, dataPtr)
  208.  
  209.     Net_InetAddress    srcIPAddress;    /* IP address of this machine. */
  210.     Net_InetAddress    destIPAddress;    /* IP address of destination. */
  211.     unsigned int    destPort;    /* UDP port of destination. */
  212.     int            dataSize;    /* Size in bytes of data in *dataPtr. */
  213.     Address        dataPtr;    /* Buffer containing data. */
  214. {
  215.     register Net_IPHeader *ipPtr;    /* Ptr to IP header. */
  216.     register Net_UDPHeader *udpPtr;    /* Ptr to UDP header. */
  217.     static    int    ident = 0;
  218.  
  219.     ipPtr  = (Net_IPHeader *) dataPtr;
  220.     udpPtr = (Net_UDPHeader *) (dataPtr + sizeof(Net_IPHeader));
  221.  
  222.     ipPtr->version    = NET_IP_VERSION;
  223.     ipPtr->headerLen    = sizeof(Net_IPHeader) / 4;
  224.     ipPtr->typeOfService = 0;
  225.     ipPtr->totalLen    = Net_HostToNetShort(sizeof(Net_IPHeader) + 
  226.                     sizeof(Net_UDPHeader) + dataSize);
  227.     ipPtr->ident    = ident++;
  228.     ipPtr->fragOffset    = 0;
  229.     ipPtr->flags    = 0;
  230.     ipPtr->timeToLive    = NET_IP_MAX_TTL;
  231.     ipPtr->protocol    = NET_IP_PROTOCOL_UDP;
  232.     ipPtr->source    = Net_HostToNetInt(srcIPAddress);
  233.     ipPtr->dest        = Net_HostToNetInt(destIPAddress);
  234.     ipPtr->checksum    = 0;
  235.     ipPtr->checksum    = 
  236.         Net_HostToNetShort(Net_InetChecksum(sizeof(Net_IPHeader), 
  237.                     (Address) ipPtr));
  238.  
  239.     udpPtr->srcPort    = Net_HostToNetShort(DBG_UDP_PORT);
  240.     udpPtr->destPort    = Net_HostToNetShort(destPort);
  241.     udpPtr->len        = Net_HostToNetShort(sizeof(Net_UDPHeader) + dataSize);
  242.     udpPtr->checksum    = 0;
  243. }
  244.  
  245.  
  246. /*
  247.  *----------------------------------------------------------------------
  248.  *
  249.  * Dbg_PacketHdrSize --
  250.  *
  251.  *    Returns the number of bytes that Dbg_FormatPacket expects to
  252.  *    format.
  253.  *
  254.  * Results:
  255.  *    The size of the packet header.
  256.  *
  257.  * Side effects:
  258.  *    None.
  259.  *
  260.  *----------------------------------------------------------------------
  261.  */
  262.  
  263. int
  264. Dbg_PacketHdrSize()
  265. {
  266.     return(sizeof(Net_IPHeader) + sizeof(Net_UDPHeader));
  267. }
  268.  
  269.  
  270. /*
  271.  *----------------------------------------------------------------------
  272.  *
  273.  * TestInputProc --
  274.  *
  275.  *    Debugging code to print the header of an IP datagram.
  276.  *
  277.  * Results:
  278.  *    None.
  279.  *
  280.  * Side effects:
  281.  *    None.
  282.  *
  283.  *----------------------------------------------------------------------
  284.  */
  285.  
  286. #ifdef DEBUG
  287.  
  288. static char srcAddr[18];
  289. static char destAddr[18];
  290.  
  291. static void
  292. TestInputProc(size, headerPtr)
  293.     int                size;
  294.     register Net_IPHeader       *headerPtr;
  295. {
  296.     unsigned short        checksum;
  297.  
  298.  
  299.     (void) Net_InetAddrToString(headerPtr->source, srcAddr);
  300.     (void) Net_InetAddrToString(headerPtr->dest, destAddr);
  301.  
  302.     printf("IP Packet: size = %d\n", size);
  303.     printf("Protocol, version:    %s, %d\n", 
  304.             ProtNumToName(headerPtr->protocol),
  305.             headerPtr->version);
  306.     printf("Src, dest addrs:    %s, %s\n", srcAddr, destAddr);
  307.     printf("Header, total len:    %d, %d\n", 
  308.             headerPtr->headerLen, headerPtr->totalLen);
  309.  
  310.     checksum = headerPtr->checksum, 
  311.     headerPtr->checksum = 0;
  312.     printf("checksum, recomp:    %x, %x\n", checksum, 
  313.         Net_InetChecksum((int)headerPtr->headerLen*4, 
  314.                     (Address)headerPtr));
  315.     printf("Frag flags, offset, ID:    %x, %d, %x\n", 
  316.             headerPtr->flags, headerPtr->fragOffset, 
  317.             headerPtr->ident);
  318.     printf("\n");
  319.  
  320.     return;
  321. }
  322.  
  323. static char *
  324. ProtNumToName(num) 
  325.     unsigned char num;
  326. {
  327.     switch (num) {
  328.     case NET_IP_PROTOCOL_IP:
  329.         return("IP");
  330.     case NET_IP_PROTOCOL_ICMP:
  331.         return("ICMP");
  332.     case NET_IP_PROTOCOL_TCP:
  333.         return("TCP");
  334.     case NET_IP_PROTOCOL_EGP:
  335.         return("EGP");
  336.     case NET_IP_PROTOCOL_UDP:
  337.         return("UDP");
  338.     default:
  339.         return("???");
  340.     }
  341. }
  342. #endif DEBUG
  343.  
  344.